 class FixPos {
	constructor(overlayId, elementClass) {
		// 初始化DOM元素
		this.overlay = document.getElementById(overlayId);
		this.fixableElements = document.querySelectorAll(`.${elementClass}`);
		
		// 设备检测
		this.screenWidth = window.screen.width;
		this.screenHeight = window.screen.height;
		this.isLandscape = this.screenWidth > this.screenHeight;
		this.isMobileDevice = this.screenWidth <= 1024;
		this.isSmallScreen = this.screenWidth < 768;
		this.isTablet = this.isMobileDevice && !this.isSmallScreen;
		this.isTabletLandscape = this.isTablet && this.isLandscape;
		
		// 状态变量
		this.elementsInfo = new Map();
		this.activeFixedElement = null;
		this.placeholderElements = new Map();
		this.keyboardActive = false;
		this.keyboardHeight = 0;
		this.keyboardRect = null; // 存储键盘位置和尺寸信息
		this.lastWindowHeight = window.innerHeight;
		this.lastVisualViewportHeight = window.visualViewport?.height || window.innerHeight;
		this.isKeyboardProcessing = false;
		this.focusTimeout = null;
		this.keyboardAdjustmentTimeout = null;
		this.keyboardStateLock = false;
		
		// 常量配置 - 为不同设备类型优化
		this.config = {
			keyboardOffset: 16,
			screenEdgeOffset: 16,
			focusDelay: this.isSmallScreen ? 150 : 200,
			keyboardDebounce: this.isTabletLandscape ? 300 : 150,
			positionCheckInterval: this.isTablet ? 100 : 200, // 平板更频繁检查
			minKeyboardHeight: this.isTabletLandscape ? 120 : 200,
			keyboardRatioMin: this.isTabletLandscape ? 0.1 : 0.2,
			keyboardRatioMax: this.isTabletLandscape ? 0.5 : 0.6,
			// 浮动键盘特殊配置
			floatingKeyboardDetection: this.isTablet, // 平板启用浮动键盘检测
			floatingCheckThreshold: 50 // 元素与键盘重叠的最小像素
		};
		
		// 初始化样式
		this.overlay.style.zIndex = '999';
		this.overlay.style.display = 'none';
		
		// 绑定事件
		this.bindEvents();
	}
	
	// 绑定所有事件
	bindEvents() {
		// 元素点击事件
		this.fixableElements.forEach(element => {
			element.classList.add('fixpos-nofixed');
			element.addEventListener('click', (e) => this.handleElementClick(e, false));
			
			// 输入框事件
			const input = element.querySelector('input, textarea');
			if (input) {
				input.addEventListener('click', (e) => this.handleElementClick(e, true));
				input.addEventListener('focus', () => this.handleInputFocus(element, input));
				input.addEventListener('blur', () => this.handleInputBlur());
			}
		});
		
		// 遮罩层和窗口事件
		this.overlay.addEventListener('click', () => this.resetAllFixedElements());
		window.addEventListener('resize', () => this.handleResize());
		window.addEventListener('scroll', () => this.handleScroll());
		
		// 方向变化事件
		window.addEventListener('orientationchange', () => {
			setTimeout(() => {
				this.handleOrientationChange();
			}, 300);
		});
		
		// 视觉视口变化事件 - 对浮动键盘特别有用
		if (window.visualViewport) {
			window.visualViewport.addEventListener('resize', () => this.handleVisualViewportChange());
			window.visualViewport.addEventListener('scroll', () => this.handleVisualViewportChange());
		}
		
		// 启动位置监控
		if (this.isMobileDevice) {
			this.startPositionMonitor();
		}
	}
	
	// 处理视觉视口变化 - 对浮动键盘检测至关重要
	handleVisualViewportChange() {
		if (!this.isMobileDevice || !this.activeFixedElement) return;
		
		const currentVpHeight = window.visualViewport?.height || window.innerHeight;
		const heightDiff = this.lastVisualViewportHeight - currentVpHeight;
		
		// 当视觉视口变化明显时检测键盘状态
		if (Math.abs(heightDiff) > 50) {
			this.detectKeyboard(true); // 传入true表示是视觉视口变化
		}
		
		this.lastVisualViewportHeight = currentVpHeight;
		
		// 如果键盘活跃，检查位置
		if (this.keyboardActive) {
			this.checkAndAdjustPosition();
		}
	}
	
	// 处理屏幕方向变化
	handleOrientationChange() {
		// 更新设备状态
		this.screenWidth = window.screen.width;
		this.screenHeight = window.screen.height;
		this.isLandscape = this.screenWidth > this.screenHeight;
		this.isTabletLandscape = this.isTablet && this.isLandscape;
		
		// 更新配置
		this.config.keyboardDebounce = this.isTabletLandscape ? 300 : 150;
		this.config.positionCheckInterval = this.isTablet ? 100 : 200;
		this.config.minKeyboardHeight = this.isTabletLandscape ? 120 : 200;
		this.config.keyboardRatioMin = this.isTabletLandscape ? 0.1 : 0.2;
		this.config.keyboardRatioMax = this.isTabletLandscape ? 0.5 : 0.6;
		
		// 重置状态
		this.resetAllFixedElements();
	}
	
	// 启动位置监控
	startPositionMonitor() {
		setInterval(() => {
			if (this.keyboardActive && this.activeFixedElement) {
				this.checkAndAdjustPosition();
			}
		}, this.config.positionCheckInterval);
	}
	
	// 检查并调整元素位置 - 支持浮动键盘
	checkAndAdjustPosition() {
		if (!this.activeFixedElement) return;
		
		const element = this.activeFixedElement;
		const elementRect = element.getBoundingClientRect();
		const viewportHeight = window.innerHeight;
		
		// 基础检查：元素是否超出视口底部
		const distanceToBottom = viewportHeight - elementRect.bottom;
		const isOffscreen = distanceToBottom < this.config.keyboardOffset || elementRect.bottom > viewportHeight;
		
		// 浮动键盘特殊检查：元素是否与键盘区域重叠
		let isOverlappingWithKeyboard = false;
		if (this.config.floatingKeyboardDetection && this.keyboardRect) {
			isOverlappingWithKeyboard = this.checkElementOverlap(elementRect, this.keyboardRect);
		}
		
		// 如果元素超出视口或与键盘重叠，需要调整
		if (isOffscreen || isOverlappingWithKeyboard) {
			this.adjustForKeyboard(true);
		}
	}
	
	// 检查两个矩形是否重叠
	checkElementOverlap(rect1, rect2) {
		// 简单的矩形重叠检测
		return rect1.left < rect2.right &&
			   rect1.right > rect2.left &&
			   rect1.top < rect2.bottom &&
			   rect1.bottom > rect2.top;
	}
	
	// 估算键盘位置和大小 - 支持浮动键盘
	estimateKeyboardRect() {
		// 对于全屏键盘，假设在底部
		if (!this.config.floatingKeyboardDetection || !this.keyboardActive) {
			return {
				top: window.innerHeight - this.keyboardHeight,
				left: 0,
				right: window.innerWidth,
				bottom: window.innerHeight,
				height: this.keyboardHeight
			};
		}
		
		// 对于平板浮动键盘，使用视觉视口变化估算
		const visualViewport = window.visualViewport;
		if (!visualViewport) return null;
		
		// 计算可视区域外的区域作为可能的键盘区域
		const viewportTop = visualViewport.pageTop;
		const viewportBottom = viewportTop + visualViewport.height;
		const viewportLeft = visualViewport.pageLeft;
		const viewportRight = viewportLeft + visualViewport.width;
		
		// 浮动键盘可能在屏幕的任何位置，这里简化处理
		// 实际应用中可能需要更复杂的算法或使用专门的API
		return {
			top: Math.max(0, Math.min(viewportTop - 50, window.innerHeight - this.keyboardHeight)),
			left: Math.max(0, viewportLeft - 50),
			right: Math.min(window.innerWidth, viewportRight + 50),
			bottom: Math.min(window.innerHeight, viewportBottom + 50),
			height: this.keyboardHeight
		};
	}
	
	// 处理元素点击
	handleElementClick(e, isInputClick) {
		const target = e.target;
		if ((target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') && !isInputClick) return;
		
		e.stopPropagation();
		const element = target.closest('.fixpos-element');
		if (!element) return;
		
		// 如果已固定则直接聚焦
		if (this.activeFixedElement === element && element.classList.contains('fixpos-fixed')) {
			if (isInputClick) target.focus({ preventScroll: true });
			return;
		}
		
		// 清除之前的定时器
		if (this.focusTimeout) clearTimeout(this.focusTimeout);
		if (this.keyboardAdjustmentTimeout) clearTimeout(this.keyboardAdjustmentTimeout);
		
		// 固定当前元素
		this.resetAllFixedElements();
		this.fixElement(element);
		
		// 输入框自动聚焦
		const inputElement = element.querySelector('input, textarea');
		if (inputElement) {
			this.focusTimeout = setTimeout(() => {
				if (this.activeFixedElement === element && document.activeElement !== inputElement) {
					inputElement.focus({ preventScroll: true });
				}
			}, isInputClick ? 0 : this.config.focusDelay);
		}
	}
	
	// 处理输入框聚焦
	handleInputFocus(element, input) {
		if (!this.isMobileDevice) return;
		
		if (this.isKeyboardProcessing || this.keyboardStateLock) return;
		
		this.isKeyboardProcessing = true;
		this.keyboardStateLock = true;
		
		if (element !== this.activeFixedElement) {
			this.resetAllFixedElements();
			this.fixElement(element);
		}
		element.style.zIndex = '1000';
		
		// 平板增加延迟，确保键盘稳定
		const focusDelay = this.isTablet ? 500 : 300;
		
		// 延迟检测键盘
		setTimeout(() => {
			this.detectKeyboard();
			// 键盘弹出后检查位置
			this.keyboardAdjustmentTimeout = setTimeout(() => {
				this.checkAndAdjustPosition();
				this.isKeyboardProcessing = false;
				// 延长锁定期
				setTimeout(() => {
					this.keyboardStateLock = false;
				}, this.isTablet ? 400 : 150);
			}, this.config.keyboardDebounce);
		}, focusDelay);
	}
	
	// 检测键盘状态 - 支持浮动键盘
	detectKeyboard(fromVisualViewport = false) {
		if (this.isKeyboardProcessing) {
			// 结合布局视口和视觉视口变化检测键盘
			const currentHeight = window.innerHeight;
			const currentVpHeight = window.visualViewport?.height || currentHeight;
			
			// 计算两种视口的高度变化
			const layoutHeightDiff = this.lastWindowHeight - currentHeight;
			const visualHeightDiff = this.lastVisualViewportHeight - currentVpHeight;
			
			// 取最大的高度变化作为参考
			const heightDiff = Math.max(layoutHeightDiff, visualHeightDiff);
			const screenRatio = heightDiff / this.screenHeight;
			
			// 键盘状态判断
			let newKeyboardActive = this.keyboardActive;
			
			// 键盘弹出判定
			if (heightDiff > this.config.minKeyboardHeight && 
				screenRatio > this.config.keyboardRatioMin && 
				screenRatio < this.config.keyboardRatioMax) {
				
				newKeyboardActive = true;
				this.keyboardHeight = heightDiff;
				this.keyboardRect = this.estimateKeyboardRect();
			} 
			// 键盘收起判定
			else if ((layoutHeightDiff < -50 || visualHeightDiff < -50) && this.keyboardActive) {
				newKeyboardActive = false;
				this.keyboardHeight = 0;
				this.keyboardRect = null;
			}
			
			// 只有状态变化时才执行调整
			if (newKeyboardActive !== this.keyboardActive) {
				this.keyboardActive = newKeyboardActive;
				this.adjustForKeyboard();
			}
			
			// 更新最后高度记录
			this.lastWindowHeight = currentHeight;
			this.lastVisualViewportHeight = currentVpHeight;
		}
	}
	
	// 调整元素位置以适应键盘 - 支持浮动键盘
	adjustForKeyboard(forceAdjust = false) {
		if (!this.activeFixedElement || !this.isMobileDevice) return;
		
		const element = this.activeFixedElement;
		const info = this.elementsInfo.get(element);
		if (!info) return;
		
		// 获取元素位置信息
		const elementRect = element.getBoundingClientRect();
		const elementHeight = elementRect.height;
		const viewportHeight = window.innerHeight;
		const viewportWidth = window.innerWidth;
		
		// 计算调整量
		let shiftAmount = 0;
		
		if (this.keyboardActive || forceAdjust) {
			// 全屏键盘处理
			if (!this.config.floatingKeyboardDetection || !this.keyboardRect) {
				const safeAreaHeight = viewportHeight - (this.keyboardActive ? this.keyboardHeight : 0) - this.config.keyboardOffset;
				const desiredBottom = Math.min(elementRect.top + elementHeight, safeAreaHeight);
				shiftAmount = (elementRect.top + elementHeight) - desiredBottom;
			} 
			// 浮动键盘处理
			else if (this.keyboardRect) {
				// 检查元素是否与键盘重叠
				if (this.checkElementOverlap(elementRect, this.keyboardRect)) {
					// 尝试将元素移到键盘上方
					if (elementRect.bottom > this.keyboardRect.top) {
						shiftAmount = elementRect.bottom - this.keyboardRect.top + this.config.keyboardOffset;
					}
					// 或者移到键盘下方（如果空间足够）
					else if (elementRect.top < this.keyboardRect.bottom && 
							 (viewportHeight - this.keyboardRect.bottom) > elementHeight) {
						shiftAmount = -(this.keyboardRect.bottom - elementRect.top + this.config.keyboardOffset);
					}
					// 或者移到屏幕左侧
					else if (elementRect.left > elementWidth) {
						element.style.left = (elementRect.left - elementWidth - this.config.keyboardOffset) + 'px';
						return; // 不需要垂直调整
					}
					// 或者移到屏幕右侧
					else if (viewportWidth - elementRect.right > elementWidth) {
						element.style.left = (elementRect.left + elementWidth + this.config.keyboardOffset) + 'px';
						return; // 不需要垂直调整
					}
				}
			}
			
			// 确保元素顶部不超过屏幕顶部
			if (elementRect.top - shiftAmount < this.config.screenEdgeOffset) {
				shiftAmount = elementRect.top - this.config.screenEdgeOffset;
			}
			
			// 应用调整
			if (Math.abs(shiftAmount) > 10 || forceAdjust) {
				const newTop = Math.max(0, elementRect.top - shiftAmount);
				element.style.transition = 'top 0.2s ease-out, left 0.2s ease-out';
				element.style.top = newTop + 'px';
			}
		} else {
			// 恢复原位
			element.style.transition = 'top 0.2s ease-out, left 0.2s ease-out';
			element.style.top = info.top;
			element.style.left = info.left;
			setTimeout(() => element.style.transition = '', 200);
		}
	}
	
	// 固定元素
	fixElement(element) {
		if (element.classList.contains('fixpos-fixed')) {
			this.activeFixedElement = element;
			return;
		}
		
		// 获取元素在视口中的精确位置
		const rect = element.getBoundingClientRect();
		const hasTransformParent = this.checkTransformParent(element);
		
		// 创建占位元素
		const placeholder = this.createPlaceholder(element);
		this.placeholderElements.set(element, placeholder);
		
		// 保存原始信息
		this.elementsInfo.set(element, {
			top: rect.top + 'px',
			//left: rect.left + 'px',
			width: rect.width,
			height: rect.height,
			viewportWidth: window.innerWidth,
			viewportHeight: window.innerHeight,
			parent: element.parentNode,
			nextSibling: element.nextSibling,
			hasTransformParent: hasTransformParent,
			originalStyles: {
				top: element.style.top,
				left: element.style.left,
				width: element.style.width,
				height: element.style.height,
				zIndex: element.style.zIndex
			}
		});
		
		// 处理transform父元素
		if (hasTransformParent) document.body.appendChild(element);
		
		// 设置固定样式
		element.classList.remove('fixpos-nofixed');
		element.classList.add('fixpos-fixed');
		element.style.top = rect.top + 'px';
		//element.style.left = rect.left + 'px';
		element.style.width = `${rect.width}px`;
		element.style.height = `${rect.height}px`;
		element.style.zIndex = '1000';
		
		// 显示遮罩
		this.overlay.style.display = 'block';
		this.activeFixedElement = element;
	}
	
	// 辅助方法：创建占位元素
	createPlaceholder(element) {
		const rect = element.getBoundingClientRect();
		const placeholder = document.createElement('div');
		placeholder.style.width = `${rect.width}px`;
		placeholder.style.height = `${rect.height}px`;
		placeholder.classList.add('fixpos-placeholder');
		
		if (element.nextSibling) {
			element.parentNode.insertBefore(placeholder, element.nextSibling);
		} else {
			element.parentNode.appendChild(placeholder);
		}
		return placeholder;
	}
	
	// 辅助方法：检查transform父元素
	checkTransformParent(element) {
		let parent = element.parentNode;
		while (parent && parent !== document.body) {
			if (window.getComputedStyle(parent).transform !== 'none') return true;
			parent = parent.parentNode;
		}
		return false;
	}
	
	// 重置所有固定元素
	resetAllFixedElements() {
		// 清除所有定时器
		if (this.focusTimeout) clearTimeout(this.focusTimeout);
		if (this.keyboardAdjustmentTimeout) clearTimeout(this.keyboardAdjustmentTimeout);
		
		this.elementsInfo.forEach((_, element) => this.resetFixedElement(element));
		this.activeFixedElement = null;
		this.overlay.style.display = 'none';
		
		// 重置键盘状态
		this.keyboardActive = false;
		this.keyboardHeight = 0;
		this.keyboardRect = null;
		this.keyboardStateLock = false;
	}
	
	// 重置单个固定元素
	resetFixedElement(element) {
		const info = this.elementsInfo.get(element);
		if (!info) return;
		
		// 恢复样式
		element.classList.remove('fixpos-fixed');
		element.classList.add('fixpos-nofixed');
		Object.keys(info.originalStyles).forEach(key => {
			element.style[key] = info.originalStyles[key];
		});
		
		// 移回原位
		if (info.hasTransformParent && info.parent) {
			if (info.nextSibling) {
				info.parent.insertBefore(element, info.nextSibling);
			} else {
				info.parent.appendChild(element);
			}
		}
		
		// 移除占位符和焦点
		this.placeholderElements.get(element)?.remove();
		this.placeholderElements.delete(element);
		element.querySelector('input, textarea')?.blur();
		this.elementsInfo.delete(element);
	}
	
	// 处理窗口大小变化
	handleResize() {
		// 更新屏幕尺寸信息
		this.screenWidth = window.screen.width;
		this.screenHeight = window.screen.height;
		this.isLandscape = this.screenWidth > this.screenHeight;
		this.isTabletLandscape = this.isTablet && this.isLandscape;
		
		// 更新配置
		this.config.keyboardDebounce = this.isTabletLandscape ? 300 : 150;
		this.config.positionCheckInterval = this.isTablet ? 100 : 200;
		this.config.minKeyboardHeight = this.isTabletLandscape ? 120 : 200;
		this.config.keyboardRatioMin = this.isTabletLandscape ? 0.1 : 0.2;
		this.config.keyboardRatioMax = this.isTabletLandscape ? 0.5 : 0.6;
		
		if (!this.isKeyboardProcessing && !this.keyboardStateLock) {
			this.resetAllFixedElements();
		} else if (this.keyboardActive) {
			this.detectKeyboard();
		}
	}
	
	// 处理窗口滚动
	handleScroll() {
		if (this.activeFixedElement && !this.isKeyboardProcessing && !this.keyboardStateLock) {
			this.resetAllFixedElements();
		}
	}
	
	// 处理输入框失焦
	handleInputBlur() {
		if (this.isKeyboardProcessing) {
			// 平板延长延迟
			const blurDelay = this.isTablet ? 500 : 300;
			setTimeout(() => {
				this.isKeyboardProcessing = false;
				this.keyboardActive = false;
				this.keyboardRect = null;
				this.keyboardStateLock = false;
			}, blurDelay);
		}
	}
}

// 初始化
document.addEventListener('DOMContentLoaded', () => {
	new FixPos('fixpos-overlay', 'fixpos-element');
});